using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AdminSG3L.Domain.Entities;
using AdminSG3L.Domain.Repositories;
using AdminSG3L.Applicaticn.ServicesInterface;
using AdminSG3L.Applicaticn.Commands;
using Serilog;
using AdminSG3L.Applicaticn.Dtos;
using AdminSG3L.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace AdminSG3L.Applicaticn.Services;

/// <summary>
/// 用户服务（原始版本，不含并发支持）
/// </summary>
public class UserService(IRepository<AppUser> userRepository, AdminDbContext dbContext) : IUserService
{
    private readonly IRepository<AppUser> _userRepository = userRepository;
    private readonly AdminDbContext _dbContext = dbContext;

    // 辅助方法：将AppUser转换为UserDto
    private static UserDto ToUserDto(AppUser user)
    {
        return new UserDto(
            user.Id,
            user.NickName,
            user.Username,
            user.Email,
            user.Avatar,
            user.Description,
            user.CreatedAt,
            user.UpdatedAt,
            user.IsActive,
            user.LoginCount,
            user.LastLoginAt,
            user.LastLoginIp
        );
    }

    public async Task<ApiResponse<AppUser?>> GetByIdAsync(Guid id)
    {
        if (id == Guid.Empty)
        {
            return ApiResponse<AppUser?>.Fail("用户ID无效");
        }
        try
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null)
            {
                return ApiResponse<AppUser?>.Fail("用户不存在");
            }
            else
            {
                return ApiResponse<AppUser?>.Success(user);
            }
        }
        catch (Exception ex)
        {
            Log.Error(ex, "获取用户异常，Id={UserId}", id);
            return ApiResponse<AppUser?>.Fail($"获取用户异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<AppUser?>> GetByIdWithIncludeAsync(Guid id)
    {
        if (id == Guid.Empty)
        {
            return ApiResponse<AppUser?>.Fail("用户ID无效");
        }
        try
        {
            // 使用DbContext直接查询，包含角色关联数据
            var user = await _dbContext.Users
                .Include(u => u.Roles.Where(r => !r.IsDeleted))
                .FirstOrDefaultAsync(u => u.Id == id && !u.IsDeleted);
            
            if (user == null)
            {
                return ApiResponse<AppUser?>.Fail("用户不存在");
            }
            
            return ApiResponse<AppUser?>.Success(user);
        }
        catch (Exception ex)
        {
            Log.Error(ex, "获取用户(含角色)异常，Id={UserId}", id);
            return ApiResponse<AppUser?>.Fail($"获取用户(含角色)异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<UserDto>> CreateAsync(CreateUserDto dto)
    {
        var user = AppUser.Create(
            dto.NickName,
            dto.Username,
            dto.PlainPassword,
            dto.Email,
            dto.Avatar,
            dto.Description
        );
        await _userRepository.AddAsync(user);
        var result = ToUserDto(user);
        return ApiResponse<UserDto>.Success(result);
    }

    public async Task<ApiResponse<IEnumerable<UserDto>>> BatchCreateAsync(IEnumerable<CreateUserDto> dtos)
    {
        var users = dtos.Select(dto => AppUser.Create(
            dto.NickName,
            dto.Username,
            dto.PlainPassword,
            dto.Email,
            dto.Avatar,
            dto.Description
        )).ToList();
        await _userRepository.AddRangeAsync(users);
        var result = users.Select(ToUserDto);
        return ApiResponse<IEnumerable<UserDto>>.Success(result);
    }

    public async Task<ApiResponse<bool>> UpdateAsync(UpdateUserDto dto)
    {
        var user = await _userRepository.GetByIdAsync(dto.Id);
        if (user == null)
            return ApiResponse<bool>.Fail("用户不存在");
        user.Update(
            dto.NickName,
            dto.Email,
            dto.Avatar,
            dto.Description,
            dto.IsActive
        );
        await _userRepository.UpdateAsync(user);
        return ApiResponse<bool>.Success(true);
    }

    public async Task<ApiResponse<bool>> DeleteAsync(Guid id)
    {
        if (id == Guid.Empty)
        {
            return ApiResponse<bool>.Fail("用户ID无效");
        }
        try
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null)
            {
                return ApiResponse<bool>.Fail("用户不存在");
            }
            
            // 检查是否已经被软删除
            if (user.IsDeleted)
            {
                return ApiResponse<bool>.Fail("用户已被删除");
            }

            // 调用实体的Delete方法（这会检查IsSystem属性）
            user.Delete();
            user.UpdateTime();
            await _userRepository.UpdateAsync(user);
            
            Log.Information("用户软删除成功，Id={UserId}", id);
            return ApiResponse<bool>.Success(true, "删除成功");
        }
        catch (Exception ex)
        {
            Log.Error(ex, "删除用户异常，Id={UserId}", id);
            return ApiResponse<bool>.Fail($"删除用户异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<int>> BatchDeleteAsync(IEnumerable<Guid> ids)
    {
        if (ids == null || !ids.Any())
        {
            return ApiResponse<int>.Fail("ID集合不能为空");
        }
        try
        {
            var users = (await _userRepository.GetAllAsync()).Where(u => ids.Contains(u.Id) && !u.IsDeleted).ToList();
            if (users.Count == 0)
            {
                return ApiResponse<int>.Fail("未找到要删除的用户或用户已被删除");
            }

            int deletedCount = 0;
            var failedUsers = new List<string>();

            // 逐个调用实体的Delete方法
            foreach (var user in users)
            {
                try
                {
                    user.Delete(); // 这会检查IsSystem属性
                    user.UpdateTime();
                    await _userRepository.UpdateAsync(user);
                    deletedCount++;
                }
                catch (InvalidOperationException ex)
                {
                    // 记录无法删除的系统用户
                    failedUsers.Add($"{user.Username}: {ex.Message}");
                    Log.Warning("用户删除被阻止，Id={UserId}, 用户名={Username}, 原因={Reason}", user.Id, user.Username, ex.Message);
                }
            }

            if (failedUsers.Any())
            {
                var message = $"批量删除完成，成功删除 {deletedCount} 个，失败 {failedUsers.Count} 个。失败原因：{string.Join("；", failedUsers)}";
                Log.Information("批量删除用户部分成功，删除数量={DeletedCount}, 失败数量={FailedCount}", deletedCount, failedUsers.Count);
                return ApiResponse<int>.Success(deletedCount, message);
            }
            else
            {
                Log.Information("批量删除用户成功，删除数量={DeletedCount}", deletedCount);
                return ApiResponse<int>.Success(deletedCount, "批量删除成功");
            }
        }
        catch (Exception ex)
        {
            Log.Error(ex, "批量删除用户异常");
            return ApiResponse<int>.Fail($"批量删除用户异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<IEnumerable<UserDto>>> GetAllDtoAsync()
    {
        try
        {
            var users = await _userRepository.GetAllAsync();
            var result = users.Select(ToUserDto);
            return ApiResponse<IEnumerable<UserDto>>.Success(result);
        }
        catch (Exception ex)
        {
            Log.Error(ex, "获取所有用户异常");
            return ApiResponse<IEnumerable<UserDto>>.Fail($"获取所有用户异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<(IEnumerable<UserDto> Users, int TotalCount)>> GetPagedDtoAsync(int pageIndex, int pageSize)
    {
        try
        {
            var all = await _userRepository.GetAllAsync();
            var total = all.Count();
            var page = all.Skip(pageIndex * pageSize).Take(pageSize).Select(ToUserDto).ToList();
            Log.Information($"分页查询: pageIndex={pageIndex}, pageSize={pageSize}, total={total}, returned={page.Count}");
            
            var result = new 
            {
                Users = page,
                TotalCount = total,
                PageIndex = pageIndex,
                PageSize = pageSize,
                TotalPages = (int)Math.Ceiling((double)total / pageSize)
            };
            
            return ApiResponse<(IEnumerable<UserDto>, int)>.Success((page, total));
        }
        catch (Exception ex)
        {
            Log.Error(ex, "分页获取用户异常");
            return ApiResponse<(IEnumerable<UserDto>, int)>.Fail($"分页获取用户异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<(IEnumerable<UserWithRolesDto> Users, int TotalCount)>> GetPagedWithRolesAsync(int pageIndex, int pageSize)
    {
        return await GetPagedWithRolesAsync(pageIndex, pageSize, null, null, null, null, null, null);
    }

    public async Task<ApiResponse<(IEnumerable<UserWithRolesDto> Users, int TotalCount)>> GetPagedWithRolesAsync(
        int pageIndex, 
        int pageSize,
        string? username = null,
        string? email = null,
        Guid? roleId = null,
        bool? isActive = null,
        DateTime? startDate = null,
        DateTime? endDate = null)
    {
        try
        {
            // 使用DbContext直接查询，包含角色关联数据，并过滤已删除的角色
            var query = _dbContext.Users
                .Where(u => !u.IsDeleted)
                .Include(u => u.Roles.Where(r => !r.IsDeleted))
                .AsQueryable();
            
            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(username))
            {
                query = query.Where(u => u.Username.Contains(username) || 
                                       (u.NickName != null && u.NickName.Contains(username)) || 
                                       u.Email.Contains(username));
            }
            
            if (!string.IsNullOrWhiteSpace(email))
            {
                query = query.Where(u => u.Email.Contains(email));
            }
            
            if (roleId.HasValue)
            {
                query = query.Where(u => u.Roles.Any(r => r.Id == roleId.Value));
            }
            
            if (isActive.HasValue)
            {
                query = query.Where(u => u.IsActive == isActive.Value);
            }
            
            if (startDate.HasValue)
            {
                query = query.Where(u => u.CreatedAt >= startDate.Value);
            }
            
            if (endDate.HasValue)
            {
                query = query.Where(u => u.CreatedAt <= endDate.Value.AddDays(1));
            }
            
            var total = await query.CountAsync();
            var users = await query
                .OrderByDescending(u => u.CreatedAt)
                .Skip(pageIndex * pageSize)
                .Take(pageSize)
                .ToListAsync();
            
            var usersWithRoles = users.Select(ToUserWithRolesDto).ToList();
            
            Log.Information($"分页查询用户(含角色和筛选): pageIndex={pageIndex}, pageSize={pageSize}, total={total}, returned={usersWithRoles.Count}");
            
            return ApiResponse<(IEnumerable<UserWithRolesDto>, int)>.Success((usersWithRoles, total));
        }
        catch (Exception ex)
        {
            Log.Error(ex, "分页获取用户(含角色和筛选)异常");
            return ApiResponse<(IEnumerable<UserWithRolesDto>, int)>.Fail($"分页获取用户(含角色和筛选)异常: {ex.Message}");
        }
    }

    // 辅助方法：将AppUser转换为UserWithRolesDto
    private static UserWithRolesDto ToUserWithRolesDto(AppUser user)
    {
        var roles = user.Roles?.Where(r => !r.IsDeleted).Select(role => new RoleDto(
            role.Id,
            role.RoleName,
            role.RoleCode,
            role.Description
        )) ?? Enumerable.Empty<RoleDto>();

        return new UserWithRolesDto(
            user.Id,
            user.NickName,
            user.Username,
            user.Email,
            user.Avatar,
            user.Description,
            user.CreatedAt,
            user.UpdatedAt,
            user.IsActive,
            user.LoginCount,
            user.LastLoginAt,
            user.LastLoginIp,
            roles
        );
    }

    public async Task<ApiResponse<int>> GetCountAsync()
    {
        try
        {
            var count = await _userRepository.CountAllAsync();
            return ApiResponse<int>.Success(count);
        }
        catch (Exception ex)
        {
            Log.Error(ex, "获取用户总数异常");
            return ApiResponse<int>.Fail($"获取用户总数异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<UserDto?>> FindOneAsync(Func<UserDto, bool> predicate)
    {
        if (predicate == null)
        {
            return ApiResponse<UserDto?>.Fail("查询条件不能为空");
        }
        try
        {
            var users = await _userRepository.GetAllAsync();
            var dtos = users.Select(ToUserDto);
            var result = dtos.FirstOrDefault(predicate);
            if (result == null)
            {
                return ApiResponse<UserDto?>.Fail("未找到用户");
            }
            else
            {
                return ApiResponse<UserDto?>.Success(result);
            }
        }
        catch (Exception ex)
        {
            Log.Error(ex, "条件查询单个用户异常");
            return ApiResponse<UserDto?>.Fail($"条件查询单个用户异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<IEnumerable<UserDto>>> FindManyAsync(Func<UserDto, bool> predicate)
    {
        if (predicate == null)
        {
            return ApiResponse<IEnumerable<UserDto>>.Fail("查询条件不能为空");
        }
        try
        {
            var users = await _userRepository.GetAllAsync();
            var dtos = users.Select(ToUserDto);
            var result = dtos.Where(predicate);
            return ApiResponse<IEnumerable<UserDto>>.Success(result);
        }
        catch (Exception ex)
        {
            Log.Error(ex, "条件查询多个用户异常");
            return ApiResponse<IEnumerable<UserDto>>.Fail($"条件查询多个用户异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<UserDto?>> GetDtoByIdAsync(Guid id)
    {
        var user = await _userRepository.GetByIdAsync(id);
        if (user == null)
            return ApiResponse<UserDto?>.Fail("用户不存在");
        var dto = ToUserDto(user);
        return ApiResponse<UserDto?>.Success(dto);
    }

    public async Task<ApiResponse<bool>> AssignRoleAsync(Guid userId, Guid roleId)
    {
        try
        {
            Log.Information("开始为用户分配角色，UserId={UserId}, RoleId={RoleId}", userId, roleId);
            
            // 获取带角色的用户
            var user = await _dbContext.Users
                .Include(u => u.Roles)
                .FirstOrDefaultAsync(u => u.Id == userId);
            
            if (user == null)
            {
                return ApiResponse<bool>.Fail("用户不存在");
            }

            // 检查角色是否存在且未被删除
            var role = await _dbContext.Roles.FindAsync(roleId);
            if (role == null || role.IsDeleted)
            {
                return ApiResponse<bool>.Fail("角色不存在或已被删除");
            }

            // 检查是否已经分配
            if (user.Roles.Any(r => r.Id == roleId))
            {
                return ApiResponse<bool>.Success(true, "该角色已经分配给用户");
            }

            // 添加角色关联
            user.Roles.Add(role);
            await _dbContext.SaveChangesAsync();
            
            Log.Information("用户角色分配成功，UserId={UserId}, RoleId={RoleId}", userId, roleId);
            return ApiResponse<bool>.Success(true, "角色分配成功");
        }
        catch (Exception ex)
        {
            Log.Error(ex, "为用户分配角色异常");
            return ApiResponse<bool>.Fail($"为用户分配角色异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<bool>> RemoveRoleAsync(Guid userId, Guid roleId)
    {
        try
        {
            Log.Information("开始移除用户的角色关联，UserId={UserId}, RoleId={RoleId}", userId, roleId);
            
            // 获取带角色的用户
            var user = await _dbContext.Users
                .Include(u => u.Roles)
                .FirstOrDefaultAsync(u => u.Id == userId);
            
            if (user == null)
            {
                return ApiResponse<bool>.Fail("用户不存在");
            }

            // 查找要移除的角色
            var roleToRemove = user.Roles.FirstOrDefault(r => r.Id == roleId);
            if (roleToRemove == null)
            {
                return ApiResponse<bool>.Success(true, "用户没有分配该角色");
            }

            // 移除角色关联
            user.Roles.Remove(roleToRemove);
            await _dbContext.SaveChangesAsync();
            
            Log.Information("用户角色移除成功，UserId={UserId}, RoleId={RoleId}", userId, roleId);
            return ApiResponse<bool>.Success(true, "角色移除成功");
        }
        catch (Exception ex)
        {
            Log.Error(ex, "移除用户角色关联异常");
            return ApiResponse<bool>.Fail($"移除用户角色关联异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<bool>> SetEnabledAsync(Guid userId, bool enabled)
    {
        try
        {
            Log.Information("开始设置用户启用状态，UserId={UserId}, Enabled={Enabled}", userId, enabled);
            
            var user = await _userRepository.GetByIdAsync(userId);
            if (user == null)
            {
                return ApiResponse<bool>.Fail("用户不存在");
            }

            user.IsActive = enabled;
            await _userRepository.UpdateAsync(user);
            
            Log.Information("用户启用状态设置成功");
            return ApiResponse<bool>.Success(true, "用户启用状态设置成功");
        }
        catch (Exception ex)
        {
            Log.Error(ex, "设置用户启用状态异常");
            return ApiResponse<bool>.Fail($"设置用户启用状态异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<bool>> ResetPasswordAsync(Guid userId, string newPassword)
    {
        try
        {
            Log.Information("开始重置用户密码，UserId={UserId}", userId);
            
            var user = await _userRepository.GetByIdAsync(userId);
            if (user == null)
            {
                return ApiResponse<bool>.Fail("用户不存在");
            }

            // 验证新密码格式
            var validationError = AdminSG3L.Applicaticn.Utils.FormValidator.ValidatePassword(newPassword);
            if (!string.IsNullOrEmpty(validationError))
            {
                return ApiResponse<bool>.Fail(validationError);
            }

            // 使用实体方法更新密码
            user.UpdatePassword(newPassword);
            
            await _userRepository.UpdateAsync(user);
            
            Log.Information("用户密码重置成功，UserId={UserId}", userId);
            return ApiResponse<bool>.Success(true, "密码重置成功");
        }
        catch (Exception ex)
        {
            Log.Error(ex, "重置用户密码异常，UserId={UserId}", userId);
            return ApiResponse<bool>.Fail($"重置用户密码异常: {ex.Message}");
        }
    }

    public async Task<ApiResponse<bool>> ChangePasswordAsync(Guid userId, string oldPassword, string newPassword)
    {
        try
        {
            Log.Information("开始修改用户密码，UserId={UserId}", userId);
            
            var user = await _userRepository.GetByIdAsync(userId);
            if (user == null)
            {
                return ApiResponse<bool>.Fail("用户不存在");
            }

            // 验证旧密码
            if (!user.VerifyPassword(oldPassword))
            {
                return ApiResponse<bool>.Fail("当前密码不正确");
            }

            // 验证新密码格式
            var validationError = AdminSG3L.Applicaticn.Utils.FormValidator.ValidatePassword(newPassword);
            if (!string.IsNullOrEmpty(validationError))
            {
                return ApiResponse<bool>.Fail(validationError);
            }

            // 使用实体方法更新密码
            user.UpdatePassword(newPassword);
            
            await _userRepository.UpdateAsync(user);
            
            Log.Information("用户密码修改成功，UserId={UserId}", userId);
            return ApiResponse<bool>.Success(true, "密码修改成功");
        }
        catch (Exception ex)
        {
            Log.Error(ex, "修改用户密码异常，UserId={UserId}", userId);
            return ApiResponse<bool>.Fail($"修改用户密码异常: {ex.Message}");
        }
    }
}
